#!/usr/bin/env python
# coding=utf-8
import psutil
import time
import math
import sys
import socket
import fcntl
import struct

from concurrent.futures import ThreadPoolExecutor

class ClassMain:
    def CpuInfo(self):
        try:
            Data = {sys._getframe().f_code.co_name: [{"CpuLoad": int(psutil.cpu_percent(interval=1, percpu=False))}]}
        except:
            Data = {sys._getframe().f_code.co_name: "Error"}
        finally:
            return Data
    def MemInfo(self):
        try:
            if psutil.swap_memory().total > 0:
                Data = {"MeMUserd": [{"physical": int(psutil.virtual_memory().used / psutil.virtual_memory().total * 100), "swap": int(psutil.swap_memory().used / psutil.swap_memory().total * 100)}]}
            else:
                Data = {"MeMUserd": [{"physical": int(psutil.virtual_memory().used / psutil.virtual_memory().total * 100), "swap": 0}]}
        except:
            Data = {sys._getframe().f_code.co_name: "Error"}
        finally:
            return Data
    def DiskInfo(self):
        try:
            Data = {sys._getframe().f_code.co_name: [{i.mountpoint: int(math.ceil(psutil.disk_usage(i.mountpoint).percent))} for i in psutil.disk_partitions()]}
        except:
            Data = {sys._getframe().f_code.co_name: "Error"}
        finally:
            return Data
    def _NetInfoS_(self, avg, net_ident):
        try:
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                HostIP = socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, struct.pack('256s', bytes(net_ident[:15], 'utf-8')))[20:24])
            except:
                HostIP = "Error"
            else:
                s.close()
            net_result = list()
            recv = psutil.net_io_counters(pernic=True).get(net_ident).bytes_recv
            sent = psutil.net_io_counters(pernic=True).get(net_ident).bytes_sent
            for x in range(0, avg):
                time.sleep(1)
                re = psutil.net_io_counters(pernic=True).get(net_ident).bytes_recv
                se = psutil.net_io_counters(pernic=True).get(net_ident).bytes_sent
                net_result.append((int(re - recv), int(se - sent)), )
                recv = re
                sent = se
            Data = {"NetCard": net_ident,
                    "HostIP": HostIP,
                    "recv": int(sum(tuple(k for k, v in net_result)) / len(tuple(k for k, v in net_result))),
                    "send": int(sum(tuple(v for k, v in net_result)) / len(tuple(v for k, v in net_result)))}
        except:
            Data = {"NetCard": net_ident, "recv": "Error", "send": "Error"}
        finally:
            return Data
    def NetInfo(self):
        try:
            avg = 3
            Data = list()
            pool = ThreadPoolExecutor(len(psutil.net_io_counters(pernic=True).keys()))
            for net_ident in psutil.net_io_counters(pernic=True).keys():
                Data.append(pool.submit(self._NetInfoS_, avg, net_ident))
            Data = {sys._getframe().f_code.co_name: list(x.result() for x in Data)}
        except:
            Data = {sys._getframe().f_code.co_name: "Error"}
        finally:
            return Data


